//package com.karaku.karaku_collector.agora;
//
//import android.content.Context;
//import android.graphics.Bitmap;
//import android.graphics.BitmapFactory;
//import android.graphics.ImageFormat;
//import android.graphics.Rect;
//import android.graphics.SurfaceTexture;
//import android.hardware.camera2.CameraAccessException;
//import android.hardware.camera2.CameraCaptureSession;
//import android.hardware.camera2.CameraCharacteristics;
//import android.hardware.camera2.CameraDevice;
//import android.hardware.camera2.CameraManager;
//import android.hardware.camera2.CameraMetadata;
//import android.hardware.camera2.CaptureRequest;
//import android.hardware.camera2.params.StreamConfigurationMap;
//import android.media.Image;
//import android.media.ImageReader;
//import android.os.Handler;
//import android.os.HandlerThread;
//import android.os.Looper;
//import android.util.AttributeSet;
//import android.util.Size;
//import android.view.Surface;
//import android.view.SurfaceHolder;
//import android.view.SurfaceView;
//import android.view.TextureView;
//import android.view.View;
//import android.view.WindowManager;
//
//import com.karaku.karaku_collector.App;
//import com.karaku.karaku_collector.LocalSetting;
//import com.karaku.karaku_collector.util.LogUtil;
//import com.karaku.karaku_collector.util.ThreadUtil;
//
//import java.lang.reflect.Method;
//import java.nio.ByteBuffer;
//import java.util.Arrays;
//import java.util.LinkedList;
//import java.util.List;
//
///**
// * Created by guoping on 2017/10/31.
// */
//
//public class CameraSurfaceView extends TextureView {
//
//    public interface Listener {
//        void openCameraFailed();
//        void openCameraSuccess();
//        void onGetFrame(byte[] frame, int width, int height);
//    }
//
//    private static CameraSurfaceView instance;
//
//    public static CameraSurfaceView getInstance() {
//        if (instance == null) {
//            instance = new CameraSurfaceView(App.getInstance());
//        }
//        return instance;
//    }
//
//    private CameraDevice cameraDevice;
//    private CameraCharacteristics cameraCharacteristics;
//    private CaptureRequest.Builder mPreviewBuilder;
//    private CameraCaptureSession cameraCaptureSession;
//    private HandlerThread cameraThread = new HandlerThread("camera");
//    private Handler handler;
//    private ImageReader mImageReader;
//    private Size mPreviewSize;
//    private float scale;
//
//    private boolean stopped = true;
//    private boolean inited = false;
//    private List<Listener> listeners = new LinkedList<>();
//
//    private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
//        @Override
//        public void onOpened(CameraDevice camera) {
//            if (stopped) {
//                return;
//            }
//            try {
//                cameraDevice = camera;
//                startPreview(camera);
//            } catch (CameraAccessException e) {
//                e.printStackTrace();
//            }
//        }
//
//        @Override
//        public void onDisconnected(CameraDevice camera) {
//        }
//
//        @Override
//        public void onError(CameraDevice camera, int error) {
//        }
//    };
//
//    private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
//        @Override
//        public void onConfigured(CameraCaptureSession session) {
//            if (stopped) {
//                return;
//            }
//            try {
//                LogUtil.d("VIDEO", "onConfigured");
//                cameraCaptureSession = session;
//                cameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
//            } catch (CameraAccessException e) {
//                LogUtil.d("VIDEO", "onConfigured1");
//                e.printStackTrace();
//            }
//        }
//
//        @Override
//        public void onConfigureFailed(CameraCaptureSession session) {
//        }
//    };
//
//    private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
//        @Override
//        public void onImageAvailable(ImageReader reader) {
//            if (stopped) {
//                return;
//            }
//            Image img = null;
//            try {
//                img = reader.acquireNextImage();
//                ByteBuffer buffer = img.getPlanes()[0].getBuffer();
//                byte[] data = new byte[buffer.remaining()];
//                buffer.get(data);
//                onGetFrame(data, img.getWidth(), img.getHeight());
//            } catch (Exception ex) {
//                ex.printStackTrace();
//            } finally {
//                if (img != null) {
//                    img.close();
//                }
//            }
//        }
//    };
//
//    SurfaceTextureListener textureListener = new SurfaceTextureListener() {
//        @Override
//        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//            LogUtil.d("VIDEO", "onSurfaceTextureAvailable");
//            if (!inited) {
//                inited = true;
//                checkStart();
//            }
//        }
//
//        @Override
//        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
//            LogUtil.d("VIDEO", "onSurfaceTextureSizeChanged");
//        }
//
//        @Override
//        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
//            return false;
//        }
//
//        @Override
//        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//
//        }
//    };
//
//    private CameraSurfaceView(Context context) {
//        super(context);
//        init();
//    }
//
//    private CameraSurfaceView(Context context, AttributeSet attributeSet) {
//        super(context, attributeSet);
//        init();
//    }
//
//    private void init() {
//        scale = LocalSetting.getInstance().getScale();
//        cameraThread.start();
//        handler = new Handler(cameraThread.getLooper());
//        setSurfaceTextureListener(textureListener);
//    }
//
//    public synchronized void removeListener(Listener listener) {
//        if (listeners.contains(listener)) {
//            listeners.remove(listener);
//        }
//    }
//
//    public synchronized void addListener(Listener listener) {
//        if (!listeners.contains(listener)) {
//            listeners.add(listener);
//        }
//    }
//
//    public void start() {
//        stopped = false;
//        checkStart();
//    }
//
//    public void stop() {
//        stopped = true;
//        if (cameraDevice != null) {
//            cameraDevice.close();
//            cameraDevice = null;
//        }
//    }
//
//    public boolean setScale(float scaleRate) {
//        scale = scaleRate;
//        if (stopped) {
//            return false;
//        }
//        updateScale();
//        try {
//            cameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
//            return true;
//        } catch (Exception ex) {
//            ex.printStackTrace();
//            return false;
//        }
//    }
//
//    private void updateScale() {
//        if (mPreviewBuilder == null) {
//            return;
//        }
//        float max = cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
//        float zoom = 1 + (max - 1) * scale;
//
//        Rect m = cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
//        Size oldSize = new Size(m.width(), m.height());
//        Size newSize = new Size((int) (oldSize.getWidth() / zoom), (int) (oldSize.getHeight() / zoom));
//
//        int x = (oldSize.getWidth() - newSize.getWidth()) / 2;
//        int y = (oldSize.getHeight() - newSize.getHeight()) / 2;
//        Rect rect = new Rect(
//                x,
//                y,
//                x + newSize.getWidth(),
//                y + newSize.getHeight());
//        mPreviewBuilder.set(CaptureRequest.SCALER_CROP_REGION, rect);
//    }
//
//    public void dispose() {
//        try {
//            Method m = TextureView.class.getDeclaredMethod("destroyHardwareLayer");
//            m.setAccessible(true);
//            m.invoke(this);
//
//            m = TextureView.class.getDeclaredMethod("releaseSurfaceTexture");
//            m.setAccessible(true);
//            m.invoke(this);
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }
//    }
//
//    protected void onDetachedFromWindowInternal() {
//    }
//
//    private void checkStart() {
//        if (inited && !stopped) {
//            final boolean success = initCamera();
//            ThreadUtil.runOnMainThread(new Runnable() {
//                @Override
//                public void run() {
//                    if (success) {
//                        onOpenCameraSuccess();
//                    } else {
//                        onOpenCameraFailed();
//                    }
//                }
//            });
//        }
//    }
//
//    private boolean initCamera() {
//        CameraManager cameraManager = (CameraManager) App.getInstance().getSystemService(Context.CAMERA_SERVICE);
//        try {
//            for (String cameraId : cameraManager.getCameraIdList()) {
//                cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
//                if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
//                    continue;
//                }
//                StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
//                mPreviewSize = getBestCameraResolution(map.getOutputSizes(SurfaceTexture.class));
//                cameraManager.openCamera(cameraId, mCameraDeviceStateCallback, handler);
//                return true;
//            }
//            return false;
//        } catch (Exception ex) {
//            ex.printStackTrace();
//            return false;
//        }
//    }
//
//    private void startPreview(CameraDevice camera) throws CameraAccessException {
//        int width = mPreviewSize.getWidth();
//        int height = mPreviewSize.getHeight();
//
//        SurfaceTexture texture = getSurfaceTexture();
//        texture.setDefaultBufferSize(width, height);
//        Surface surface = new Surface(texture);
//
//        try {
//            mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); // 设置捕获请求为预览，这里还有拍照啊，录像等
//        } catch (CameraAccessException e) {
//            e.printStackTrace();
//        }
//
//        mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);// 自动对焦
//        mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF); // 关闭闪光灯
//        updateScale();
//
//        mImageReader = ImageReader.newInstance(width, height, ImageFormat.FLEX_RGBA_8888, 2);
//        mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
//
//        mPreviewBuilder.addTarget(surface);
//        mPreviewBuilder.addTarget(mImageReader.getSurface());
//        cameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), mSessionStateCallback, null);
//    }
//
//    private Size getBestCameraResolution(Size[] ss) {
//        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
//        Size screenResolution = new Size(wm.getDefaultDisplay().getWidth(), wm.getDefaultDisplay().getHeight());
//        float tmp = 0f;
//        float mindiff = 100f;
//        float x_d_y = (float) screenResolution.getWidth() / (float) screenResolution.getHeight();
//        Size best = null;
//        for (Size s : ss) {
//            tmp = Math.abs(((float) s.getHeight() / (float) s.getWidth()) - x_d_y);
//            if (tmp < mindiff) {
//                mindiff = tmp;
//                best = s;
//            }
//        }
//        return best;
//    }
//
//    private synchronized void onOpenCameraSuccess() {
//        for (Listener l: listeners) {
//            l.openCameraSuccess();
//        }
//    }
//
//    private synchronized void onOpenCameraFailed() {
//        for (Listener l: listeners) {
//            l.openCameraFailed();
//        }
//    }
//
//    private synchronized void onGetFrame(byte[] frame, int width, int height) {
//        for (Listener l: listeners) {
//            l.onGetFrame(frame, width, height);
//        }
//    }
//}
